package com.hulk.boot.common.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

import lombok.extern.slf4j.Slf4j;

import com.google.common.base.Strings;

/**
 * @author cmt
 * 
 */
@Slf4j
public class SocketClientUtil {

	public static byte[] sendMsg(String ip, int port, byte[] msgBytes,
			int timeout) {

		if (Strings.isNullOrEmpty(ip) || 0 == port) {
			throw new RuntimeException("ip or port is null");
		}
		log.info("ip:" + ip + "  port:" + port + "  timeout:" + timeout);
		byte[] responseBytes = null;
		InputStream is = null;
		OutputStream os = null;
		Socket socket = new Socket();
		try {
			socket.setReuseAddress(true);// 为了确保一个进程关闭了ServerSocket后，即使操作系统还没释放端口，同一个主机上的其他进程还可以立刻重用该端口,必须在绑定端口前使用
			socket.connect(new InetSocketAddress(ip, port), timeout);
			socket.setSoTimeout(timeout);
			socket.setTcpNoDelay(false);// 启用Nagle算法
			if (socket.getSoLinger() == -1)
				socket.setSoLinger(true, 0); // 关闭延迟close
			socket.setSendBufferSize(4096);
			socket.setReceiveBufferSize(4096);
			socket.setKeepAlive(false);// 关闭心跳包
			os = socket.getOutputStream();
			os.write(msgBytes);
			//os.flush();
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			is = socket.getInputStream();
			// bis = new ByteArrayInputStream(is);
			byte[] receiveBuffer = new byte[4096];
			int len = -1;
			while ((len = is.read(receiveBuffer)) != -1) {
				bos.write(receiveBuffer, 0, len);
			}

			// int readBytesSize = is.read(receiveBuffer);
			// do {
			// bos.write(receiveBuffer, 0, readBytesSize);
			// readBytesSize = is.read(receiveBuffer);
			// } while (readBytesSize != -1);
			responseBytes = bos.toByteArray();
			return responseBytes;
		} catch (Exception e) {
			e.printStackTrace();
			log.info("", e);
			throw new RuntimeException("socket Connection closed.", e);
			// return null ;
		} finally {

			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
					log.info("", e);
				}
			}
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
					log.info("", e);
				}
			}
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
					log.info("", e);
				}
			}

		}

	}

}
